package com.mokylin.dbschema.util;

import com.mokylin.dbschema.config.ConfigInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 读环境变量
 * @author Li Zhao
 * @since 2016/5/19.
 */
public class EnvConfigUtils {

    private static final Logger log = LoggerFactory.getLogger(ConfigInfo.class);

    private static Properties prop = new Properties();

    static {
        prop = new Properties();
        try {
            prop.load(ConfigInfo.class.getClassLoader().getResourceAsStream("dbschema.properties"));
        } catch (Exception e) {
            log.info("no properties config file:dbschema.properties");
        }
        prop.putAll(System.getenv());
        prop.putAll(System.getProperties());
    }

    private static ScriptEngineManager manager = new ScriptEngineManager();

    private static ScriptEngine jsEngine = manager.getEngineByName("JavaScript");

    private static Object getEval(Enum key) throws ScriptException {
        return getEval(key.toString());
    }

    private static Object getEval(String key) throws ScriptException {
        return getEval(key, null);
    }

    private static Object getEval(String key,Object defaultVal) throws ScriptException {
        String val = getString(key);
        if (val == null) {
            return defaultVal;
        }
        return jsEngine.eval(val);
    }

    private EnvConfigUtils() {
    }

    public static String getString(Enum key) {
        return getString(key.name());
    }

    public static long getLong(Enum key) {
        return getLong(key.toString());
    }

    public static long getLong(String key) {
        return getLong(key,0L);
    }

    public static Long getLong(String key,long defaultVal){
        try {
            Object eval = getEval(key,defaultVal);
            if (eval instanceof Number) {
                long i = ((Number) eval).longValue();
                prop.put(key, i);
                return i;
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return defaultVal;
    }

    public static int getInt(Enum key) {
        return getInt(key.toString());
    }

    public static int getInt(String key,int defaultVal){
        try {
            Object eval = getEval(key,defaultVal);
            if (eval instanceof Number) {
                int i = ((Number) eval).intValue();
                prop.put(key, i);
                return i;
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return defaultVal;
    }

    public static Properties getProp() {
        return prop;
    }

    public static String getString(String str) {
        return prop.getProperty(str);
    }

    public static String getString(String str,String defaultVal) {
        return prop.getProperty(str,defaultVal);
    }


    public static int getInt(String key) {
        return getInt(key,0);
    }

    public static Map<String, String> getStringByRegex(String regex) {
        Map<String, String> res = new HashMap<>();
        prop.keySet().stream().filter(key -> key.toString().matches(regex))
                .forEach(key -> res.put(key.toString(), getString(key.toString())));
        return res;
    }

    public static Map<String, Integer> getIntByRegex(String regex) {
        Map<String, Integer> res = new HashMap<>();
        prop.keySet().stream().filter(key -> key.toString().matches(regex))
                .forEach(key -> res.put(key.toString(), getInt(key.toString())));
        return res;
    }

    public static boolean getBoolean(String key) {
        return Boolean.parseBoolean(getString(key));
    }

}
